package com.foo.common.base.utils.laboratory;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;

import com.foo.common.base.utils.FooUtils;
import com.foo.common.base.utils.laboratory.httpClient.MavenSearchResultJson;
import com.google.common.base.Stopwatch;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;

import static org.junit.Assert.assertTrue;

/**
 * This class simulate the process of zznode IMTS login
 */
public class HttpClientHelper {

    static final Logger logger = FooUtils.getRootLogger();

    @Test
    public void test_loginAndGet()
            throws Exception {
        CloseableHttpClient httpClient = getHttpClient();

        Gson gson = new Gson();

        HttpPost httpPost = new HttpPost(
                "https://100.115.13.208:8088/deviceManager/rest/123/sessions");

        StringEntity stringEntity = new StringEntity(gson.toJson(
                ImmutableMap.of("username", "admin", "password", "Admin@tool2",
                        "scope", "0")),
                "UTF-8");
        stringEntity.setContentEncoding("UTF-8");
        stringEntity.setContentType("application/json");
        httpPost.setEntity(stringEntity);

        httpPost.setHeader("Cache-Control", "no-cache");
        httpPost.setHeader("Content-Language", "en");
        httpPost.setHeader("Content-Type", "application/json; charset=utf-8");
        httpPost.setHeader("Server", "Apache/1.3.27 (Unix) (Red-Hat/Linux)");
        httpPost.setHeader("Location", "http://www.huawei.com");

        CloseableHttpResponse response = httpClient.execute(httpPost);

        String cookie = "";
        try {
            logger.info("status:{}", response.getStatusLine());
            logger.info("length:{}", response.getAllHeaders().length);

            for (Header item : response.getAllHeaders()) {
                logger.info("item:{} with value:{}", item.getName(),
                        item.getValue());
                if (item.getName().equals("Set-Cookie")
                        && !"".equals(item.getValue())) {
                    cookie = item.getValue();
                    logger.info("before transform:{}", cookie);
                    cookie = cookie.substring(0,
                            cookie.indexOf(";"));
                    logger.info("after transform:{}", cookie);
                    break;
                }

            }

            HttpEntity entity = response.getEntity();
// do something useful with the response body
// and ensure it is fully consumed
            String httpReturn = EntityUtils.toString(entity);
// EntityUtils.consume(entity2);
            logger.info("{}", httpReturn);
            Map asanJson = gson.fromJson(httpReturn, Map.class);

            assertTrue(asanJson != null);

            logger.info("{}", httpReturn);
            HttpGet httpGet = new HttpGet(
                    "https://100.115.13.208:8088/deviceManager/rest/"
                            + "123"
                            + "/system_timezone");
            CloseableHttpResponse getResponse = httpClient.execute(httpGet);

            httpGet.setHeader("Cache-Control", "no-cache");
            httpGet.setHeader("Content-Language", "en");
            httpGet.setHeader("Content-Type",
                    "application/json; charset=utf-8");
            httpGet.setHeader("Server", "Apache/1.3.27 (Unix) (Red-Hat/Linux)");
            httpGet.setHeader("Location", "http://www.huawei.com");
            httpGet.setHeader("iBaseToken", "");
            httpGet.setHeader("Cookie", cookie);

            logger.info("request now:{}",
                    EntityUtils.toString(getResponse.getEntity()));

        } finally {
            response.close();
        }
    }

    @Test
    public void parseJson() {
        String json = "{\"data\":{\"accountstate\":1,\"deviceid\":\"21023598251234567895\",\"iBaseToken\":\"645CB465DC04F7CE15A762121BE21BE0C8B9E72678A787418D7DE6F3E3696505\",\"lastloginip\":\"8.46.120.23\",\"lastlogintime\":1483442954,\"level\":1,\"pwdchangetime\":1479021455,\"usergroup\":\"\",\"username\":\"admin\",\"userscope\":\"0\"},\"error\":{\"code\":0,\"description\":\"0\"}}";
        Gson gson = new Gson();
        Map asanJson = gson.fromJson(json, Map.class);
        logger.info("{}", "");
    }

    private CloseableHttpClient getHttpClient()
            throws Exception {
        TrustStrategy trustStrategy = new TrustStrategy() {
            @Override
            public boolean isTrusted(X509Certificate[] x509Certificates,
                                     String s)
                    throws CertificateException {
                return true;
            }
        };

        SSLContext sslContext = SSLContexts.custom()
                .loadTrustMaterial(null, trustStrategy).build();

        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslContext,
                NoopHostnameVerifier.INSTANCE);

        CloseableHttpClient httpclient = HttpClients.custom()
                .setSSLSocketFactory(sslsf)
                .build();

        return httpclient;
    }

    @Test
    public void test_noPrivilegeGet()
            throws Exception {
        CloseableHttpClient httpclient = getHttpClient();

        try {
            HttpGet httpget = new HttpGet(
                    "https://100.115.13.208:8088/deviceManager/rest/21023598251234567895/lun/0");

            System.out.println("Executing request " + httpget.getRequestLine());

// Create a custom response handler
            ResponseHandler<String> responseHandler = new ResponseHandler<String>() {

                @Override
                public String handleResponse(
                        final HttpResponse response)
                        throws ClientProtocolException, IOException {
                    int status = response.getStatusLine().getStatusCode();
                    if (status >= 200 && status < 300) {
                        HttpEntity entity = response.getEntity();
                        return entity != null ?
                                EntityUtils.toString(entity) :
                                null;
                    } else {
                        throw new ClientProtocolException(
                                "Unexpected response status: " + status);
                    }
                }

            };
            String responseBody = httpclient.execute(httpget, responseHandler);
            System.out.println("----------------------------------------");
            System.out.println(responseBody);
        } finally {
            httpclient.close();
        }

    }


    public static void main33(String[] args) throws ClientProtocolException,
            IOException {
        String groupId = "org.springframework";
        String artifactId = "spring-web";

        logger.info("groupId:【{}】 and artifactId:【{}】 analyze start.", groupId,
                artifactId);

        Stopwatch stopwatch = Stopwatch.createStarted();

        CloseableHttpClient httpclient = HttpClients.createDefault();

        String url = "http://search.maven.org/solrsearch/select?q=g:%22com.jhlabs%22+AND+a:%22filters %22&rows=1&wt=json";

        ResponseHandler<String> responseHandler = new BasicResponseHandler();
        HttpGet httpGet = new HttpGet(url);
        String responseBody = httpclient.execute(httpGet, responseHandler);
        // responseBody = new String(responseBody.getBytes("ISO-8859-1"),
        // "UTF-8");

        Gson gson = new GsonBuilder().serializeNulls().create();
        MavenSearchResultJson object = new MavenSearchResultJson();
        object = gson.fromJson(responseBody, MavenSearchResultJson.class);

        stopwatch.stop();
        logger.info(
                "groupId:【{}】 and artifactId:【{}】 analyze end.Newest version:【{}】",
                groupId, artifactId, object.getVersion());
        logger.info("all cost time:{}", stopwatch);
    }

    public static void main5(String[] args) throws IOException {

        String groupId = "commons-net";
        String artifactId = "commons-net";

        logger.info("groupId:【{}】 and artifactId:【{}】 analyze start.", groupId,
                artifactId);

        Stopwatch stopwatch = Stopwatch.createStarted();

        CloseableHttpClient httpclient = HttpClients.createDefault();

        String url = "http://search.maven.org/solrsearch/select?q=g:%22"
                + groupId + "%22+AND+a:%22" + artifactId + "%22&rows=1&wt=json";

        logger.info("request url is:{}", url);

        ResponseHandler<String> responseHandler = new BasicResponseHandler();
        HttpGet httpGet = new HttpGet(url);
        String responseBody = httpclient.execute(httpGet, responseHandler);
        // responseBody = new String(responseBody.getBytes("ISO-8859-1"),
        // "UTF-8");

        Gson gson = new GsonBuilder().serializeNulls().create();
        MavenSearchResultJson object = new MavenSearchResultJson();
        object = gson.fromJson(responseBody, MavenSearchResultJson.class);

        stopwatch.stop();
        logger.info(
                "groupId:【{}】 and artifactId:【{}】 analyze end.Newest version:【{}】",
                groupId, artifactId, object.getVersion());
        logger.info("all cost time:{}", stopwatch);

    }

    public static void main2(String[] args) throws Exception {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpResponse response1 = null;

        HttpPost httpPost = new HttpPost(
                "http://192.168.2.112:9980/itms/pages/security/loginAction.action");

        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("user.password", "asb#1234"));
        nvps.add(new BasicNameValuePair("user.userName", "administrator"));
        httpPost.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));

        response1 = httpclient.execute(httpPost);

        EntityUtils.consume(response1.getEntity());

        System.out.println(response1.getStatusLine());
        httpPost.releaseConnection();

        System.out.println("---------------------");
        ResponseHandler<String> responseHandler = new BasicResponseHandler();
        HttpPost httpPost2 = new HttpPost(
                "http://192.168.2.112:9980/itms/pages/generic/refreshUserTables.action");
        String responseBody = httpclient.execute(httpPost2, responseHandler);
        responseBody = new String(responseBody.getBytes("ISO-8859-1"), "UTF-8");
        System.out.println(responseBody);
        httpPost2.releaseConnection();
    }

    public static void main(String[] args) {
        HttpClient httpClient = new HttpClient();

        httpClient.getState().setCredentials(
                new AuthScope("127.0.0.1", 8080, null),
                new UsernamePasswordCredentials("tomcat", "tomcat"));
        httpClient.getParams().setAuthenticationPreemptive(true);

        // GetMethod getMethod = new GetMethod(
        // "http://127.0.0.1:8080/feiYnn-manager/text/start?path=/");
        GetMethod getMethod = new GetMethod(
                "http://127.0.0.1:8080/feiYnn-manager/text/vminfo");
        getMethod.setDoAuthentication(true);
        getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
                new DefaultHttpMethodRetryHandler());
        try {
            int statusCode = httpClient.executeMethod(getMethod);
            if (statusCode != HttpStatus.SC_OK) {
                System.err.println("Method failed: "
                        + getMethod.getStatusLine());
            }
            byte[] responseBody = getMethod.getResponseBody();
            System.out.println(new String(responseBody));
        } catch (HttpException e) {
            System.out.println("Please check your provided http address!");
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            getMethod.releaseConnection();
        }
    }
}
